
package biblio.service.aop.logging;


import java.lang.reflect.Method;
import java.util.EnumMap;
import java.util.Map;

import org.aopalliance.intercept.MethodInvocation;

import biblio.service.aop.logging.interfaces.UniversalAdvice;


/**
 * Default implementation of {@link biblio.aop.logging.interfaces.UniversalAdvice}.
 * @author mephisto
 * 2011-10-26
 */
public class UniversalAdviceImpl implements UniversalAdvice
{
    public UniversalAdviceImpl()
    {
        this(null);
    }

    public UniversalAdviceImpl(Map<AdviceType, LoggerLevel> map)
    {
        adviceTypeLevelMap = new EnumMap<AdviceType, LoggerLevel>(AdviceType.class);
        for (AdviceType it : DEFAULT_ADVICE_TYPE_LEVEL_MAP.keySet())
            adviceTypeLevelMap.put(it, DEFAULT_ADVICE_TYPE_LEVEL_MAP.get(it));
        if (map != null)
            for (AdviceType it : map.keySet())
                adviceTypeLevelMap.put(it, map.get(it));
    }

    public void before(Method method, Object[] args, Object target) throws Throwable
    {
        UniversalAdviceTemplate.before(
                adviceTypeLevelMap.get(AdviceType.BEFORE), method, args, target);
    }

    public void afterReturning(Object returnValue, Method method, Object[] args,
            Object target) throws Throwable
    {
        UniversalAdviceTemplate.afterReturning(
                adviceTypeLevelMap.get(AdviceType.AFTER_RETURNING),
                returnValue, method, args, target);
    }

    public void afterThrowing(Method method, Object[] args, Object target,
            Exception e) throws Throwable
    {
        UniversalAdviceTemplate.afterThrowing(
                adviceTypeLevelMap.get(AdviceType.AFTER_THROWING), method, args,
                target, e);
    }

    public Object invoke(MethodInvocation invocation) throws Throwable
    {
        return UniversalAdviceTemplate.invoke(LoggerLevel.DEBUG, invocation);
    }


    private static Map<AdviceType, LoggerLevel> DEFAULT_ADVICE_TYPE_LEVEL_MAP = null;
    private Map<AdviceType, LoggerLevel> adviceTypeLevelMap = null;

    static
    {
        DEFAULT_ADVICE_TYPE_LEVEL_MAP = new EnumMap<AdviceType, LoggerLevel>(AdviceType.class);
        DEFAULT_ADVICE_TYPE_LEVEL_MAP.put(AdviceType.BEFORE, LoggerLevel.DEBUG);
        DEFAULT_ADVICE_TYPE_LEVEL_MAP.put(AdviceType.AFTER_RETURNING, LoggerLevel.DEBUG);
        DEFAULT_ADVICE_TYPE_LEVEL_MAP.put(AdviceType.AFTER_THROWING, LoggerLevel.ERROR);
        DEFAULT_ADVICE_TYPE_LEVEL_MAP.put(AdviceType.AROUND, LoggerLevel.DEBUG);
    }
}
